package api

import (
	"bytes"
	"fmt"
	"github.com/fatih/color"
	"github.com/gin-gonic/gin"
	"github.com/go-resty/resty/v2"
	"io/ioutil"
	"net/http"
	"os/exec"
	"strconv"
	"strings"
	"web-collect-server/entity"
	"web-collect-server/entity/common/response"
	"web-collect-server/global"
)

// BanData 板卡返回数据
type BanData struct {
	Sigus []Sigus `json:"sigus"`
}

// CmdRes 命令行结果
type CmdRes struct {
	Str1 string `json:"str1"`
	Str2 string `json:"str2"`
}
type FpgaType struct {
	Fpga1type string `json:"fpga1type"`
	Fpga2type string `json:"fpga2type"`
}

type Ports struct {
	TwoMcnt  int    `json:"2mcnt"`
	Six4Kcnt int    `json:"64kcnt"`
	B1       int    `json:"b1"`
	B2       int    `json:"b2"`
	B3       int    `json:"b3"`
	E1Cnt    int    `json:"e1cnt"`
	Lof      int    `json:"lof"`
	Los      int    `json:"los"`
	Port     int    `json:"port"`
	Type     string `json:"type"`
}
type Sigus struct {
	FpgaType string  `json:"fpga_type"`
	Fpgaid   int     `json:"fpgaid"`
	Ports    []Ports `json:"ports"`
}

// InitDeviceRouter 设备路由初始化
func InitDeviceRouter(r *gin.RouterGroup) {
	g := r.Group("/device")
	g.GET("/data", getData)
	g.GET("", getBanDevice)
	g.GET("/fpgaType", getFpgaType)
	g.GET("/statistic", getStatistic)   // 调用命令行命令 统计
	g.GET("/clear", clearStatistic)     // 调用命令行命令 清除 统计
	g.GET("/otherTable", getOtherTable) // 调用命令行命令 获取另一个列表
	g.GET("/time", getCurrentTime)      // 调用命令行命令 获取本机时间
	g.GET("/startExe", startExe)        // 调用命令行命令 启动程序
	g.GET("/stopExe", stopExe)          // 调用命令行命令 停止程序
	g.GET("/exeStatus", exeStatus)      // 调用命令行命令 停止程序
	g.GET("/long", getLong)             // 获取运行时长
	g.POST("/time", setCurrentTime)     // 调用命令行命令 设置本机时间
	g.POST("/fpgaType", setFpgaType)
}

func getLong(c *gin.Context) {
	// sh /root/dap_charon/bin/stop.sh
	cmd1 := exec.Command("cat", "/proc/uptime")
	stdout1, err := cmd1.Output()
	if err != nil {
		sprintf := fmt.Sprintf("执行命令行命令  cat /proc/uptime  失败! err.Error() -> %+v", err.Error())
		response.FailWithMessage(sprintf, c)
		return
	}
	s1 := string(stdout1)
	res := CmdRes{Str1: s1}
	response.OkWithData(res, c)
}

func stopExe(c *gin.Context) {
	// sh /root/dap_charon/bin/stop.sh
	cmd1 := exec.Command("sh", "/root/dap_charon/bin/stop.sh")
	stdout1, err := cmd1.Output()
	if err != nil {
		sprintf := fmt.Sprintf("执行命令行命令  sh /root/dap_charon/bin/stop.sh  失败! err.Error() -> %+v", err.Error())
		response.FailWithMessage(sprintf, c)
		return
	}
	s1 := string(stdout1)
	res := CmdRes{Str1: s1}
	response.OkWithData(res, c)
}
func exeStatus(c *gin.Context) {
	//$ sh /root/dap_charon/bin/ps.sh
	//cmd := exec.Command("grep", host, "test")
	//var out bytes.Buffer
	//var stderr bytes.Buffer
	//cmd.Stdout = &out
	//cmd.Stderr = &stderr
	//err := cmd.Run()
	//if err != nil {
	//	log.Error(err.Error(), stderr.String())
	//} else {
	//	log.Info(out.String())
	//}

	cmd1 := exec.Command("sh", "/root/dap_charon/bin/ps.sh")

	var out bytes.Buffer
	var stderr bytes.Buffer
	cmd1.Stdout = &out
	cmd1.Stderr = &stderr
	err := cmd1.Run()
	if err != nil {
		sprintf := fmt.Sprintf("执行命令行命令  sh /root/dap_charon/bin/ps.sh  失败! err.Error() -> %+v  -> %+v", err.Error(), stderr.String())
		color.Blue(sprintf)
		response.OkWithData(CmdRes{Str1: "2"}, c)

		return
	}
	s1 := out.String()
	res := CmdRes{Str1: strings.Trim(s1, "\n")}
	response.OkWithData(res, c)
}

func startExe(c *gin.Context) {
	// sh /root/dap_charon/bin/start.sh
	cmd1 := exec.Command("sh", "/root/dap_charon/bin/start.sh")
	stdout1, err := cmd1.Output()
	if err != nil {
		sprintf := fmt.Sprintf("执行命令行命令  sh /root/dap_charon/bin/start.sh  失败! err.Error() -> %+v", err.Error())
		response.FailWithMessage(sprintf, c)
		return
	}
	s1 := string(stdout1)
	res := CmdRes{Str1: s1}
	response.OkWithData(res, c)
}

func getCurrentTime(c *gin.Context) {
	//  echo $(date '+%Y-%m-%d %H:%M:%S')
	//执行 echo $(date '+%!Y(string=exit status 1)-%!m(MISSING)-%!d(MISSING) %!H(MISSING):%!M(MISSING):%!S(MISSING)')! err.Error() -> %!v(MISSING)
	cmd1 := exec.Command("date", "+%Y-%m-%d %H:%M:%S")
	stdout1, err := cmd1.Output()
	if err != nil {
		color.Blue("执行 echo $(date '+%Y-%m-%d %H:%M:%S')! err.Error() -> %+v", err.Error())
		response.FailWithMessage("执行 echo $(date '+%Y-%m-%d %H:%M:%S')! err.Error() 失败", c)
		return
	}
	s1 := string(stdout1)
	trim := strings.Trim(s1, "\n")
	res := CmdRes{Str1: trim}
	response.OkWithData(res, c)
}
func setCurrentTime(c *gin.Context) {
	var strDto entity.LoginRes
	_ = c.BindJSON(&strDto)
	//  echo $(date '+%Y-%m-%d %H:%M:%S')
	//执行 echo $(date '+%!Y(string=exit status 1)-%!m(MISSING)-%!d(MISSING) %!H(MISSING):%!M(MISSING):%!S(MISSING)')! err.Error() -> %!v(MISSING)
	cmd1 := exec.Command("date", "-s", strDto.Token)
	stdout1, err := cmd1.Output()
	if err != nil {
		color.Blue("执行 date -s 失败  err.Error() -> %+v", err.Error())
		response.FailWithMessage("执行  date -s 失败  失败", c)
		return
	}
	s1 := string(stdout1)
	trim := strings.Trim(s1, "\n")
	res := CmdRes{Str1: trim}
	response.OkWithData(res, c)
}

func getOtherTable(c *gin.Context) {
	//cmdcli 127.0.0.1:13000 port-info
	cmd1 := exec.Command("cmdcli", "127.0.0.1:13000", "port-info")
	stdout1, err := cmd1.Output()
	if err != nil {
		sprintf := fmt.Sprintf("执行命令行命令  cmdcli 127.0.0.1:13000 port-info  失败! err.Error() -> %+v", err.Error())
		response.FailWithMessage(sprintf, c)
		return
	}
	s1 := string(stdout1)
	res := CmdRes{Str1: s1}
	response.OkWithData(res, c)
}

func clearStatistic(c *gin.Context) {
	// 用命令行清除本机
	//cmdcli 172.168.10.195:12000 count-clear
	cmd1 := exec.Command("cmdcli", "127.0.0.1:11000", "count-clear")
	stdout1, err := cmd1.Output()
	if err != nil {
		sprintf := fmt.Sprintf("执行命令行命令  cmdcli 127.0.0.1:11000 count-clear  失败! err.Error() -> %+v", err.Error())
		response.FailWithMessage(sprintf, c)
		return
	}
	s1 := string(stdout1)
	cmd2 := exec.Command("cmdcli", "127.0.0.1:12000", "count-clear")
	stdout2, err2 := cmd2.Output()
	if err2 != nil {
		sprintf := fmt.Sprintf("执行命令行命令  cmdcli 127.0.0.1:12000 count-clear  失败! err.Error() -> %+v", err.Error())
		response.FailWithMessage(sprintf, c)
		return
	}
	s2 := string(stdout2)
	res := CmdRes{Str1: s1, Str2: s2}

	// 用调用http清除板卡 统计
	//http get http://192.168.10.60:8081/telecom_ac/bcode_clear
	// 获取单个板卡信息
	var banDevice entity.BanDevice
	global.DB.First(&banDevice)
	var fullIp string
	if banDevice.Ip == "" {
		color.Blue("没有找到ip")
		fullIp = "http://192.168.10.60:8081/telecom_ac/bcode_clear"
	} else {
		fullIp = "http://" + banDevice.Ip + ":8081/telecom_ac/bcode_clear"
		color.Blue("找到ip 为 fullIp -> %+v", fullIp)
	}
	client := resty.New()

	fpgaType := FpgaType{}
	resp, err := client.R().EnableTrace().SetResult(&fpgaType).Get(fullIp)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	color.Blue("fullIp -> %+v", fullIp)
	color.Blue("resp.StatusCode() -> %+v", resp.StatusCode())
	if resp.StatusCode() != http.StatusOK {
		response.FailWithMessage("清除板卡统计 请求失败 ,状态码"+strconv.Itoa(resp.StatusCode()), c)
		return
	}
	response.OkWithData(res, c)
}

// 设置fpga类型
func setFpgaType(c *gin.Context) {
	fpgaType := FpgaType{}
	err := c.ShouldBindJSON(&fpgaType)
	if err != nil {
		color.Blue("绑定fpgaType失败!")
		response.FailWithMessage(err.Error(), c)
		return
	}
	var fullIp string
	var banDevice entity.BanDevice
	global.DB.First(&banDevice)
	if banDevice.Ip == "" {
		color.Blue("没有找到ip")
		fullIp = "http://192.168.10.60:8081/telecom_ac/fpga_type"
	} else {
		fullIp = "http://" + banDevice.Ip + ":8081/telecom_ac/fpga_type"
		color.Blue("找到ip 为 fullIp -> %+v", fullIp)
	}

	bodyJson := `{ "fpga1type":"` + fpgaType.Fpga1type + `" , "fpga2type": "` + fpgaType.Fpga2type + `" }`
	color.Blue("bodyJson -> %+v", bodyJson)
	jsonStr := []byte(bodyJson)
	//url := "https://www.denlery.top/api/v1/login"
	req, err := http.NewRequest("POST", fullIp, bytes.NewBuffer(jsonStr))
	req.Header.Set("Content-Type", "application/json")

	client := &http.Client{}
	resp, err := client.Do(req)
	if err != nil {
		color.Red("请求板卡失败! %+v", err.Error())
		response.Ok(c)
		return
	}
	defer resp.Body.Close()

	statuscode := resp.StatusCode
	if statuscode != http.StatusOK {
		response.FailWithMessage("请求板卡失败!", c)
		return
	}
	hea := resp.Header
	body, _ := ioutil.ReadAll(resp.Body)
	color.Blue("string(body) -> %+v", string(body))
	color.Blue("statuscode -> %+v", statuscode)
	color.Blue("hea -> %+v", hea)

	response.Ok(c)
}

// 获取fpga类型
func getFpgaType(c *gin.Context) {
	// 获取单个板卡信息
	var banDevice entity.BanDevice
	global.DB.First(&banDevice)
	var fullIp string
	if banDevice.Ip == "" {
		color.Blue("没有找到ip")
		fullIp = "http://192.168.10.60:8081/telecom_ac/get/fpga_type"
	} else {
		fullIp = "http://" + banDevice.Ip + ":8081/telecom_ac/get/fpga_type"
		color.Blue("找到ip 为 fullIp -> %+v", fullIp)
	}
	client := resty.New()

	fpgaType := FpgaType{}
	resp, err := client.R().EnableTrace().SetResult(&fpgaType).Get(fullIp)
	if err != nil {
		response.FailWithMessage(err.Error(), c)
		return
	}
	color.Blue("fullIp -> %+v", fullIp)
	color.Blue("resp.StatusCode() -> %+v", resp.StatusCode())
	if resp.StatusCode() != http.StatusOK {
		response.FailWithMessage("获取板卡信息 请求失败 ,状态码"+strconv.Itoa(resp.StatusCode()), c)
		return
	}

	response.OkWithData(fpgaType, c)
}

// 获取板卡设备
func getBanDevice(c *gin.Context) {
	// 获取单个板卡信息
	var banDevice entity.BanDevice
	global.DB.First(&banDevice)
	response.OkWithData(banDevice, c)
}

// 调用命令行命令 统计
func getStatistic(c *gin.Context) {
	cmd1 := exec.Command("cmdcli", "127.0.0.1:11000", "e1-count")
	stdout1, err := cmd1.Output()
	if err != nil {
		sprintf := fmt.Sprintf("执行命令行命令  cmdcli, 127.0.0.1:11000, e1-count  失败! err.Error() -> %+v", err.Error())
		response.FailWithMessage(sprintf, c)
		return
	}
	s1 := string(stdout1)
	cmd2 := exec.Command("cmdcli", "127.0.0.1:12000", "e1-count")
	stdout2, err2 := cmd2.Output()
	if err2 != nil {
		sprintf := fmt.Sprintf("执行命令行命令  cmdcli, 127.0.0.1:12000, e1-count  失败! err.Error() -> %+v", err.Error())
		response.FailWithMessage(sprintf, c)
		return
	}
	s2 := string(stdout2)
	res := CmdRes{Str1: s1, Str2: s2}
	response.OkWithData(res, c)
}

// 根据 单个设备(ip ) 获取  数据
func getData(c *gin.Context) {
	client := resty.New()
	banData := BanData{}
	// 获取单个板卡信息
	var banDevice entity.BanDevice
	global.DB.First(&banDevice)
	var fullIp string
	if banDevice.Ip == "" {
		color.Blue("没有找到ip")
		fullIp = "http://192.168.10.60:8081/telecom_ac/sigus"
	} else {
		fullIp = "http://" + banDevice.Ip + ":8081/telecom_ac/sigus"
		color.Blue("找到ip 为 fullIp -> %+v", fullIp)
	}
	resp, err := client.R().EnableTrace().SetResult(&banData).Get(fullIp)
	if err != nil {
		sprintf := fmt.Sprintf("请求板卡 失败! err.Error() -> %+v", err.Error())
		response.FailWithMessage(sprintf, c)
		return
	}
	if resp.StatusCode() != http.StatusOK {
		response.FailWithMessage("请求 板卡 失败", c)
		return
	}

	response.OkWithData(banData, c)
}
